package com.xzh.homeliving.commodity.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.xzh.homeliving.commodity.dao.AttrAtRelationDao;
import com.xzh.homeliving.commodity.dao.AttrDao;
import com.xzh.homeliving.commodity.entity.AttrAtRelationEntity;
import com.xzh.homeliving.commodity.entity.AttrEntity;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xzh.common.utils.PageUtils;
import com.xzh.common.utils.Query;

import com.xzh.homeliving.commodity.dao.AtDao;
import com.xzh.homeliving.commodity.entity.AtEntity;
import com.xzh.homeliving.commodity.service.AtService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;


/**
 * @author xzh
 */
@Service("atService")
public class AtServiceImpl extends ServiceImpl<AtDao, AtEntity> implements AtService {
    @Resource
    private AttrAtRelationDao attrAtRelationDao;

    @Resource
    private AttrDao attrDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {

        IPage<AtEntity> page = this.page(
                new Query<AtEntity>().getPage(params),
                new QueryWrapper<>()
        );

        return new PageUtils(page);
    }

    /**
     * 这里由于同时进行了两次数据持久化操作，所以需要进行事务控制
     */
    @Transactional
    @Override
    public void saveAttrRelation(AtEntity atEntity) {
        this.save(atEntity);
        if(atEntity.getAttrType() == 1 && atEntity.getAttrGroupId() != null) {
            AttrAtRelationEntity attrAtRelationEntity = new AttrAtRelationEntity();
            attrAtRelationEntity.setAttrGroupId(atEntity.getAttrGroupId());
            attrAtRelationEntity.setAttrId(atEntity.getAttrId());
            attrAtRelationDao.insert(attrAtRelationEntity);
        }
    }

    @Transactional
    @Override
    public void updateAttrRelation(AtEntity atEntity) {
        if(atEntity.getAttrType() == 1 && atEntity.getAttrGroupId() != null) {
            UpdateWrapper<AttrAtRelationEntity> updateWrapper = new UpdateWrapper<>();
            updateWrapper.set("attr_group_id", atEntity.getAttrGroupId()).eq("attr_id", atEntity.getAttrId());
            attrAtRelationDao.update(null, updateWrapper);
        }
        this.updateById(atEntity);
    }

    @Transactional
    @Override
    public void deleteAttrRelation(Long[] ids) {
        QueryWrapper<AttrAtRelationEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("attr_id", Arrays.asList(ids));
        attrAtRelationDao.delete(queryWrapper);
        this.removeByIds(Arrays.asList(ids));
    }

    @Override
    public PageUtils queryBaseAttrPage(Map<String, Object> params, Long categoryId) {
        // 取出检索关键字
        String key = (String)params.get("key");
        // 创建一个基本属性(attr_type = 1)的wrapper
        QueryWrapper<AtEntity> queryWrapper = new QueryWrapper<AtEntity>().eq("attr_type", 1);
        return getPageUtils(params, categoryId, key, queryWrapper);
    }

    private PageUtils getPageUtils(Map<String, Object> params, Long categoryId, String key, QueryWrapper<AtEntity> queryWrapper) {
        if(categoryId != 0) {
            queryWrapper.eq("category_id", categoryId);
        }
        if(StringUtils.isNotBlank(key)) {
            queryWrapper.and((obj) -> obj.eq("attr_id", key).or().like("attr_name", key));
        }
        IPage<AtEntity> page = this.page(
                new Query<AtEntity>().getPage(params),
                queryWrapper
        );
        return new PageUtils(page);
    }

    @Override
    public PageUtils querySaleAttrPage(Map<String, Object> params, Long categoryId) {
        String key = (String)params.get("key");
        QueryWrapper<AtEntity> queryWrapper = new QueryWrapper<AtEntity>().eq("attr_type", 0);
        return getPageUtils(params, categoryId, key, queryWrapper);
    }

    @Override
    public List<AtEntity> getRelationAttr(Long attrGroupId) {
        // 1. 根据 attrGroupID, 到 commodity_attr_attrGroup_relation 表中，查询关联的基本属性
        List<AttrAtRelationEntity> entityList = attrAtRelationDao.selectList(new QueryWrapper<AttrAtRelationEntity>().eq("attr_group_id", attrGroupId));
        // 2. 将 entities 收集到集合中
        List<Long> attrIds = entityList.stream().map(AttrAtRelationEntity::getAttrId).collect(Collectors.toList());
        // 3. 根据 attrIds 获取对应的 AtEntity
        if(attrIds.isEmpty()) {
            return null;
        }
        Collection<AtEntity> atEntities = this.listByIds(attrIds);
        return (List<AtEntity>)atEntities;
    }

    /**
     * 实现批量删除属性和属性组的关联关系
     * @param attrAtRelationEntities 属性和属性组的关联关系表
     */
    @Override
    public void deleteAttrGroupRelation(AttrAtRelationEntity[] attrAtRelationEntities) {
        attrAtRelationDao.deleteBatchRelation(Arrays.asList(attrAtRelationEntities));
    }

    @Override
    public PageUtils getBaseAttrFromAttrGroup(Map<String, Object> params, Long attrGroupId) {
        // 1. 通过attrGroupId获取对应的属性组实体
        AttrEntity attrGroupEntity = attrDao.selectById(attrGroupId);
        // 2. 再通过得到的属性组实体，得到其所属分类id
        Long categoryId = attrGroupEntity.getCategoryId();
        // 3. 创建对应的 wrapper，检索到所有所属类相同并且为基础属性的属性
        QueryWrapper<AtEntity> queryWrapper = new QueryWrapper<AtEntity>().eq("category_id", categoryId).eq("attr_type", 1);
        // 4. 排除已关联属性和属性组--------------------------
        List<AttrAtRelationEntity> attrAtRelationEntities = attrAtRelationDao.selectList(new QueryWrapper<AttrAtRelationEntity>().in("attr_group_id", attrGroupId));
        List<Long> attrIds = attrAtRelationEntities.stream().map(AttrAtRelationEntity::getAttrId).collect(Collectors.toList());
        if(!attrIds.isEmpty()) {
            queryWrapper.notIn("attr_id", attrIds);
        }

        // 5. 获取检索关键字------------------------------
        String key = (String) params.get("key");
        if(StringUtils.isNoneBlank(key)) {
            queryWrapper.and((obj) -> obj.eq("attr_id", key).or().like("attr_name", key));
        }

        IPage<AtEntity> page = this.page(
                new Query<AtEntity>().getPage(params),
                queryWrapper
        );
        return new PageUtils(page);
    }
}